/**
 * @file 统一应用初始化服务
 * @description 提供统一的应用初始化入口，整合所有初始化逻辑
 * @date 2024-08-14 (更新)
 */
// @ts-ignore
import { ref, computed, watch } from 'vue';
import { logger } from '@/utils/system/logger';
import { useMapStore } from '@/stores/modules/map';

// ===== 类型定义 =====

/**
 * 初始化层级
 */
export enum InitLevel {
  CORE = 'core',       // 核心框架层 (Vue, Pinia等)
  SERVICE = 'service', // 服务层 (API, 地图等)
  BUSINESS = 'business' // 业务层 (业务逻辑)
}

/**
 * 初始化优先级
 */
export enum InitPriority {
  HIGH = 0,    // 高优先级 - 关键功能
  NORMAL = 1,  // 普通优先级 - 常规功能
  LOW = 2      // 低优先级 - 可延迟加载功能
}

/**
 * 初始化任务配置
 */
export interface InitTaskConfig {
  name: string;                   // 任务名称
  level: InitLevel;               // 所属层级
  priority: InitPriority;         // 优先级
  handler: () => Promise<void>;   // 处理函数
  routeCondition?: string[];      // 路由条件，仅在特定路由下执行
  dependencies?: string[];        // 依赖任务
  description?: string;           // 任务描述
  timeout?: number;               // 任务超时时间(ms)，默认30秒
}

/**
 * 统一初始化服务
 */
class AppInitializer {
  // 单例实例
  private static instance: AppInitializer;
  
  // 状态管理
  private _initialized = ref<boolean>(false);
  private _initializing = ref<boolean>(false);
  private _error = ref<any>(null);
  private _currentTask = ref<string>('');
  
  // 任务管理
  private tasks = new Map<string, InitTaskConfig>();
  private executedTasks = new Set<string>();
  private sortedTasksCache: InitTaskConfig[] | null = null;
  
  // 当前路由
  private currentRoute = '';
  
  // 统计信息缓存
  private statsCache: Record<string, any> | null = null;
  
  // 私有构造函数
  private constructor() {}
  
  /**
   * 获取单例实例
   */
  public static getInstance(): AppInitializer {
    if (!AppInitializer.instance) {
      AppInitializer.instance = new AppInitializer();
    }
    return AppInitializer.instance;
  }
  
  /**
   * 初始化状态计算属性
   */
  public get initialized(): boolean {
    return this._initialized.value;
  }
  
  public get initializing(): boolean {
    return this._initializing.value;
  }
  
  public get error(): any {
    return this._error.value;
  }
  
  public get currentTask(): string {
    return this._currentTask.value;
  }
  
  /**
   * 注册初始化任务
   * @param config 任务配置
   */
  public registerTask(config: InitTaskConfig): AppInitializer {
    const finalConfig = { timeout: 30000, ...config }; // 默认30秒超时
    
    if (this.tasks.has(finalConfig.name)) {
      logger.warn(`任务 "${finalConfig.name}" 已存在，将被覆盖`);
    }
    
    this.tasks.set(finalConfig.name, finalConfig);
    // 任务更新时清除缓存
    this.invalidateCache();
    
    logger.debug(`注册初始化任务: ${finalConfig.name} (${finalConfig.level}层, ${InitPriority[finalConfig.priority]}优先级)`);
    return this;
  }
  
  /**
   * 注册多个初始化任务
   * @param configs 任务配置数组
   */
  public registerTasks(configs: InitTaskConfig[]): AppInitializer {
    configs.forEach(config => this.registerTask(config));
    return this;
  }
  
  /**
   * 设置当前路由
   * @param route 当前路由路径
   */
  public setCurrentRoute(route: string): void {
    if (this.currentRoute !== route) {
      this.currentRoute = route;
      logger.debug(`设置当前路由: ${route}`);
    }
  }
  
  /**
   * 初始化应用
   * 按照层级和优先级执行任务
   */
  public async initialize(): Promise<void> {
    // 已初始化或正在初始化时不再执行
    if (this._initialized.value || this._initializing.value) {
      return;
    }
    
    this._initializing.value = true;
    this._error.value = null;
    
    try {
      logger.info('开始统一初始化流程');
      
      // 按层级依次执行任务
      const sortedTasks = this.getSortedTasks();
      const levelGroups = this.groupTasksByLevel(sortedTasks);
      
      // 执行各层级任务
      for (const level of Object.values(InitLevel)) {
        const levelTasks = levelGroups[level] || [];
        if (levelTasks.length === 0) continue;
        
        logger.info(`执行 ${level} 层初始化任务 (${levelTasks.length}个)`);
        await this.executeLevelTasks(levelTasks);
      }
      
      this._initialized.value = true;
      logger.info('统一初始化流程完成');
      
    } catch (error) {
      this._error.value = error;
      logger.error('初始化过程中发生错误:', error);
    } finally {
      this._initializing.value = false;
      this._currentTask.value = '';
      this.invalidateCache(); // 初始化完成后清除缓存
    }
  }
  
  /**
   * 执行指定层级的所有任务
   * @param tasks 当前层级的任务列表
   */
  private async executeLevelTasks(tasks: InitTaskConfig[]): Promise<void> {
    // 将任务按优先级分组，以便同优先级任务可以并行执行
    const tasksByPriority: Record<string, InitTaskConfig[]> = {};
    
    // 任务分组
    for (const task of tasks) {
      const priorityKey = task.priority.toString();
      if (!tasksByPriority[priorityKey]) {
        tasksByPriority[priorityKey] = [];
      }
      tasksByPriority[priorityKey].push(task);
    }
    
    // 按优先级顺序执行任务组
    const priorities = Object.keys(tasksByPriority).sort((a, b) => Number(a) - Number(b));
    
    for (const priority of priorities) {
      const priorityTasks = tasksByPriority[priority];
      logger.debug(`并行执行 ${priorityTasks.length} 个优先级为 ${priority} 的任务`);
      
      // 同一优先级的任务并行执行
      await Promise.all(
        priorityTasks.map(task => this.executeTask(task))
      );
    }
  }
  
  /**
   * 执行单个初始化任务
   * @param task 任务配置
   */
  private async executeTask(task: InitTaskConfig): Promise<void> {
    // 已执行过的任务直接跳过
    if (this.executedTasks.has(task.name)) {
      return;
    }
    
    // 检查路由条件
    if (!this.checkRouteCondition(task)) {
      logger.debug(`任务 "${task.name}" 路由条件不满足，跳过执行`);
      return;
    }
    
    // 执行依赖任务
    if (task.dependencies && task.dependencies.length > 0) {
      await this.executeDependencies(task);
    }
    
    this._currentTask.value = task.name;
    logger.debug(`执行初始化任务: ${task.name}`);
    
    try {
      await this.executeWithTimeout(task);
      this.executedTasks.add(task.name);
      logger.debug(`任务 "${task.name}" 执行完成`);
      
    } catch (error) {
      logger.error(`任务 "${task.name}" 执行失败:`, error);
      throw error;
    }
  }
  
  /**
   * 检查任务的路由条件是否满足
   * @param task 任务配置
   */
  private checkRouteCondition(task: InitTaskConfig): boolean {
    // 没有路由条件则认为任何路由下都可执行
    if (!task.routeCondition || task.routeCondition.length === 0) {
      return true;
    }
    
    // 检查当前路由是否满足条件
    return task.routeCondition.some(route => {
      if (route.endsWith('*')) {
        const prefix = route.slice(0, -1);
        return this.currentRoute.startsWith(prefix);
      } else {
        return this.currentRoute === route || this.currentRoute.includes(route);
      }
    });
  }
  
  /**
   * 执行任务的依赖项
   * @param task 任务配置
   */
  private async executeDependencies(task: InitTaskConfig): Promise<void> {
    if (!task.dependencies || task.dependencies.length === 0) {
      return;
    }
    
    for (const depName of task.dependencies) {
      const depTask = this.tasks.get(depName);
      if (!depTask) {
        logger.warn(`任务 "${task.name}" 依赖的任务 "${depName}" 不存在`);
        continue;
      }
      
      // 递归执行依赖任务
      await this.executeTask(depTask);
    }
  }
  
  /**
   * 带超时执行任务
   * @param task 任务配置
   */
  private executeWithTimeout(task: InitTaskConfig): Promise<void> {
    return new Promise<void>((resolve, reject) => {
      const timeoutId = setTimeout(() => {
        reject(new Error(`任务 "${task.name}" 执行超时 (${task.timeout}ms)`));
      }, task.timeout);
      
      task.handler().then(resolve).catch(reject).finally(() => {
        clearTimeout(timeoutId);
      });
    });
  }
  
  /**
   * 将任务按层级分组
   * @param tasks 已排序的任务
   */
  private groupTasksByLevel(tasks: InitTaskConfig[]): Record<string, InitTaskConfig[]> {
    const groups: Record<string, InitTaskConfig[]> = {};
    
    for (const task of tasks) {
      if (!groups[task.level]) {
        groups[task.level] = [];
      }
      groups[task.level].push(task);
    }
    
    return groups;
  }
  
  /**
   * 获取经过排序的任务列表
   * 按照层级和优先级排序
   */
  private getSortedTasks(): InitTaskConfig[] {
    // 使用缓存提高性能
    if (this.sortedTasksCache) {
      return this.sortedTasksCache;
    }
    
    // 转换为数组并排序
    const taskList = Array.from(this.tasks.values());
    
    // 按照层级和优先级排序
    taskList.sort((a, b) => {
      // 首先按照层级排序
      const levelOrder = Object.values(InitLevel).indexOf(a.level) - 
                        Object.values(InitLevel).indexOf(b.level);
      
      if (levelOrder !== 0) {
        return levelOrder;
      }
      
      // 层级相同时按优先级排序
      return a.priority - b.priority;
    });
    
    this.sortedTasksCache = taskList;
    return taskList;
  }
  
  /**
   * 使缓存失效
   */
  private invalidateCache(): void {
    this.sortedTasksCache = null;
    this.statsCache = null;
  }
  
  /**
   * 获取初始化统计信息
   */
  public getStats(): Record<string, any> {
    // 使用缓存提高性能
    if (this.statsCache) {
      return this.statsCache;
    }
    
    const stats = {
      initialized: this._initialized.value,
      initializing: this._initializing.value,
      error: this._error.value ? true : false,
      currentTask: this._currentTask.value,
      totalTasks: this.tasks.size,
      executedTasks: this.executedTasks.size,
      pendingTasks: this.tasks.size - this.executedTasks.size,
      tasksByLevel: {} as Record<string, number>,
      tasksByPriority: {} as Record<string, number>,
    };
    
    // 按层级和优先级统计
    for (const task of this.tasks.values()) {
      // 按层级统计
      if (!stats.tasksByLevel[task.level]) {
        stats.tasksByLevel[task.level] = 0;
      }
      stats.tasksByLevel[task.level]++;
      
      // 按优先级统计
      const priorityName = InitPriority[task.priority];
      if (!stats.tasksByPriority[priorityName]) {
        stats.tasksByPriority[priorityName] = 0;
      }
      stats.tasksByPriority[priorityName]++;
    }
    
    this.statsCache = stats;
    return stats;
  }
  
  /**
   * 重置初始化状态
   * 仅用于测试或特殊情况
   */
  public reset(): void {
    this._initialized.value = false;
    this._initializing.value = false;
    this._error.value = null;
    this._currentTask.value = '';
    this.executedTasks.clear();
    this.invalidateCache();
    
    logger.info('应用初始化器已重置');
  }
}

// 导出单例实例
export const appInitializer = AppInitializer.getInstance();

/**
 * 注册核心初始化任务
 * 这些任务是应用启动必须的基础功能
 */
export function registerCoreInitTasks(): void {
  const mapStore = useMapStore();
  
  appInitializer.registerTasks([
    // 日志系统初始化
    {
      name: 'core:logger',
      level: InitLevel.CORE,
      priority: InitPriority.HIGH,
      description: '初始化日志系统',
      handler: async () => {
        logger.info('日志系统初始化完成');
      }
    },
    
    // 状态存储初始化
    {
      name: 'core:store',
      level: InitLevel.CORE,
      priority: InitPriority.HIGH,
      dependencies: ['core:logger'],
      description: '初始化状态存储',
      handler: async () => {
        logger.info('状态存储初始化完成');
      }
    },
    
    // 地图服务初始化 - 简化为单一任务
    {
      name: 'service:map',
      level: InitLevel.SERVICE,
      priority: InitPriority.NORMAL,
      dependencies: ['core:store'],
      description: '初始化地图服务',
      routeCondition: ['/pages/monitor', '/monitor', '/track'],
      handler: async () => {
        logger.info('开始初始化地图服务');
        
        // 检查当前路由是否需要地图
        if (!mapStore.isMapRouteActive()) {
          logger.info('当前路由不需要地图资源，跳过初始化');
          return;
        }
        
        // 检查地图资源状态
        if (mapStore.isMapReady && mapStore.isTrackReady) {
          logger.info('地图资源已全部就绪，无需再次加载');
          return;
        }
        
        // 按需加载地图资源
        try {
          const loadResult = await mapStore.loadMapOnDemand({
            loadTrack: true,
            retry: true,
            maxRetries: 3
          });
          
          if (loadResult) {
            logger.info('地图资源加载成功');
          } else {
            logger.warn('地图资源加载未成功完成');
          }
        } catch (err) {
          logger.error('地图资源加载过程中发生错误:', err);
          throw new Error('地图资源加载失败');
        }
      }
    }
  ]);
}

/**
 * 带重试的函数执行
 * @param fn 要执行的函数
 * @param options 重试选项
 */
async function tryWithRetry<T>(
  fn: () => Promise<T>,
  options: {
    maxRetries: number,
    retryDelay: (attempt: number) => number,
    onRetry?: (error: any, attempt: number) => void,
    onSuccess?: (attempt: number) => void,
    onFinalFailure?: (error: any) => void
  }
): Promise<T> {
  let lastError: any = null;
  let attempt = 0;
  
  while (attempt <= options.maxRetries) {
    try {
      const result = await fn();
      // 成功回调
      if (options.onSuccess) {
        options.onSuccess(attempt);
      }
      return result;
    } catch (error) {
      lastError = error;
      attempt++;
      
      // 达到最大重试次数
      if (attempt > options.maxRetries) {
        if (options.onFinalFailure) {
          options.onFinalFailure(error);
        }
        break;
      }
      
      // 重试回调
      if (options.onRetry) {
        options.onRetry(error, attempt);
      }
      
      // 延迟一段时间后重试
      const delay = options.retryDelay(attempt);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
  
  throw lastError || new Error('操作失败，已达到最大重试次数');
} 